﻿namespace ChinaUnicom
{
    using ChinaUnicom.Models;
    using ChinaUnicom.Schedule;
    using ChinaUnicom.Tasks;
    using Microsoft.Phone.Controls;
    using Microsoft.Phone.Shell;
    using System;
    using System.Windows;
    using System.Windows.Media.Imaging;

    public partial class Settings : PhoneApplicationPage
    {
        IScheduleQuene taskQueue;

        Context Context { get { return (Application.Current as App).Context; } }

        bool logining = false;

        public Settings()
        {
            taskQueue = new Schedule.SerialQuene();
            taskQueue.Error += OnTaskQueueError;

            InitializeComponent();

            Loaded += OnPageLoaded;
        }

        AutoLoginTask AutoLoginTask
        {
            get
            {
                AutoLoginTask.Task.Failed -= OnAutoLoginFailed;
                AutoLoginTask.Task.Completed -= OnSigned;
                AutoLoginTask.Task.Failed += OnAutoLoginFailed;
                AutoLoginTask.Task.Completed += OnSigned;
                return AutoLoginTask.Task;
            }
        }

        ApplicationBarIconButton loginIconButton;
        ApplicationBarIconButton LoginIconButton
        {
            get
            {
                if (loginIconButton == null)
                {
                    loginIconButton = new ApplicationBarIconButton();
                    loginIconButton.Text = "登录";
                    loginIconButton.Click += OnLoginIconButtonClick;
                    loginIconButton.IconUri = new Uri("/Themes/Images/login.png", UriKind.Relative);
                }

                return loginIconButton;
            }
        }

        void OnLoginIconButtonClick(object sender, EventArgs e)
        {
            DoLogin();
        }

        Account Account { get { return (Application.Current as App).Context.Account; } }

        void OnSigned(object sender, EventArgs e)
        {
            this.Dispatcher.BeginInvoke(() => SetupAccount());

            AutoLoginTask.Task.Failed -= OnAutoLoginFailed;
            AutoLoginTask.Task.Completed -= OnSigned;
        }

        void OnAutoLoginFailed(object sender, EventArgs e)
        {
            AutoLoginTask task = sender as AutoLoginTask;
            this.Dispatcher.BeginInvoke(() => MessageBox.Show(task.Message, "温馨提示", MessageBoxButton.OK));

            AutoLoginTask.Task.Failed -= OnAutoLoginFailed;
            AutoLoginTask.Task.Completed -= OnSigned;
        }

        void OnTaskQueueError(object sender, ScheduleExceptionArgs e)
        {
            this.Dispatcher.BeginInvoke(() =>
            {
                MessageBox.Show(e.Exception.Message, "温馨提示", MessageBoxButton.OK);
            });
        }

        void OnPageLoaded(object sender, RoutedEventArgs e)
        {
            if (Authentication.Current.Authorized && Authentication.Current.Signed)
            {
                SetupAccount();
            }
            else if (Authentication.Current.Authorized)
            {
                taskQueue.Schedule(AutoLoginTask);
            }
            else
            {
                CreateSessionTask csTask = new CreateSessionTask();
                csTask.Failed += OnCreateSessionFailed;

                CodeImageTask gisTask = new CodeImageTask();
                gisTask.Completed += ImageStreamCallback;

                // schedule
                // 1. Create session
                taskQueue.Schedule(csTask);
                // 2. initialize the code image
                taskQueue.Schedule(gisTask);

                signedPanel.Visibility = System.Windows.Visibility.Collapsed;
                loginPanel.Visibility = System.Windows.Visibility.Visible;
            }
        }

        void SetupAccount()
        {
            clientName.Text = Account.ClientName;
            mobileNumber.Text = Account.Mobile;
        }

        void OnCreateSessionFailed(object sender, EventArgs e)
        {
            CreateSessionTask task = sender as CreateSessionTask;
            this.Dispatcher.BeginInvoke(() => MessageBox.Show(task.Message, "温馨提示", MessageBoxButton.OK));
        }

        void ImageStreamCallback(object sender, EventArgs e)
        {
            CodeImageTask task = sender as CodeImageTask;

            this.Dispatcher.BeginInvoke(() =>
            {
                BitmapImage bitmap = new BitmapImage();
                bitmap.SetSource(task.Stream);
                imgCode.Source = bitmap;
            });
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            if (NavigationContext.QueryString.ContainsKey("login"))
            {
                mainContainer.SelectedIndex = 1;
            }

            base.OnNavigatedTo(e);
        }

        private void OnBackButtonClick(object sender, EventArgs e)
        {
            if (!Authentication.Current.Authorized)
            {
                return;
            }

            NavigationService.GoBack();
        }
        
        private void OnPasswordGotFocus(object sender, System.Windows.RoutedEventArgs e)
        {
            passwordHint.Visibility = System.Windows.Visibility.Collapsed;
        }

        private void OnPasswordLostFocus(object sender, System.Windows.RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(password.Password))
            {
                passwordHint.Visibility = System.Windows.Visibility.Visible;
            }
        }

        private void OnPivotSelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
        {
            Pivot p = sender as Pivot;
            if (p.SelectedIndex == 0)
            {
                if (ApplicationBar.Buttons.Contains(LoginIconButton))
                {
                    ApplicationBar.Buttons.Remove(LoginIconButton);
                }
            }
            else if (p.SelectedIndex == 1)
            {
                if (!Authentication.Current.Authorized)
                {
                    ApplicationBar.Buttons.Add(LoginIconButton);
                }
            }
        }

        private void OnLogoutClick(object sender, System.Windows.RoutedEventArgs e)
        {
            if (Authentication.Current.Authorized)
            {
                Authentication.Current.Logout();
            }

            CreateSessionTask csTask = new CreateSessionTask();
            csTask.Failed += OnCreateSessionFailed;

            CodeImageTask gisTask = new CodeImageTask();
            gisTask.Completed += ImageStreamCallback;

            // schedule
            // 1. Create session
            taskQueue.Schedule(csTask);
            // 2. initialize the code image
            taskQueue.Schedule(gisTask);

            signedPanel.Visibility = System.Windows.Visibility.Collapsed;
            loginPanel.Visibility = System.Windows.Visibility.Visible;
        }

        #region login

        private void OnLoginClick(object sender, RoutedEventArgs e)
        {
            DoLogin();
        }

        private void DoLogin()
        {
            if (logining)
            {
                return;
            }

            if (!LoginChecking())
            {
                return;
            }

            logining = true;

            BeforeLogin();

            // do logining.
            Logining();
        }

        bool LoginChecking()
        {
            if (string.IsNullOrEmpty(mobile.Text))
            {
                mobile.Focus();
                return false;
            }

            if (mobile.Text.Length != 11)
            {
                MessageBox.Show("手机号码必须是11位的数字！", "温馨提示", MessageBoxButton.OK);
                mobile.Focus();
                return false;
            }

            if (string.IsNullOrEmpty(password.Password))
            {
                password.Focus();
                return false;
            }

            if (string.IsNullOrEmpty(code.Text))
            {
                code.Focus();
                return false;
            }

            Context.Account.Mobile = mobile.Text;
            Context.Account.Password = password.Password;

            return true;
        }

        void BeforeLogin()
        {
            mainContainer.Focus();
            coverRect.Visibility = System.Windows.Visibility.Visible;
            loginingText.Visibility = System.Windows.Visibility.Visible;
        }

        void Logining()
        {
            LoginTask lTask = new LoginTask(mobile.Text, password.Password, code.Text);
            lTask.Completed += OnLoginCompleted;
            lTask.Failed += OnLoginFailed;
            lTask.AfterLogin += AfterLogin;

            ClientTask cTask = new ClientTask();
            cTask.Completed += (sender, e) => Dispatcher.BeginInvoke(() => SetupAccount());

            taskQueue.Schedule(lTask);
            taskQueue.Schedule(cTask);
        }

        void AfterLogin(object sender, EventArgs e)
        {
            this.Dispatcher.BeginInvoke(() =>
            {
                coverRect.Visibility = System.Windows.Visibility.Collapsed;
                loginingText.Visibility = System.Windows.Visibility.Collapsed;
            });
            logining = false;
        }

        void OnLoginCompleted(object sender, EventArgs e)
        {
            this.Dispatcher.BeginInvoke(() =>
            {
                password.Password = string.Empty;
                mobileNumber.Text = Context.Account.Mobile;
                clientName.Text = Context.Account.ClientName;

                loginPanel.Visibility = System.Windows.Visibility.Collapsed;
                signedPanel.Visibility = System.Windows.Visibility.Visible;
            });
        }

        void OnLoginFailed(object sender, EventArgs e)
        {
            LoginTask task = sender as LoginTask;
            this.Dispatcher.BeginInvoke(() => MessageBox.Show(task.Message, "温馨提示", MessageBoxButton.OK));
        }

        #endregion

        protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
        {
            if (!Authentication.Current.Authorized)
            {
                try
                {
                    while (NavigationService.RemoveBackEntry() != null) ;
                }
                catch { }
            }

            base.OnBackKeyPress(e);
        }
    }
}